import '@coms/jquery.flot'
import '@coms/jquery.flot.pie'
import '@coms/jquery.flot.time'
import '@coms/jquery.flot.categories'
import '@coms/jquery.flot.barnumbers'

import {
	getDbDetailApi,
} from '@utils/apis'

let _plotDiskIO = null
let _plotBufferPool = null
let _plotNetworkStatus = null
let _plotDbConnection = null
let _ioReadData = null
let _ioWriteData = null
let _netRecivedData = null
let _netSendData = null
const _xMax = 100
const _rateOldData = {
	ioRead: {
		count: 0,
		time_elapsed: 0,
	},
	ioWrite: {
		count: 0,
		time_elapsed: 0,
	},
	netRecived: {
		count: 0,
		time_elapsed: 0,
	},
	netSend: {
		count: 0,
		time_elapsed: 0,
	},
	readRequest: {
		count: 0,
		time_elapsed: 0,
	},
	writeRequest: {
		count: 0,
		time_elapsed: 0,
	},
	diskRead: {
		count: 0,
		time_elapsed: 0,
	},
}

module.exports = {
	init: async function() {
		// disk io
		_plotDiskIO = $.plot("#innodb-disk-io", [], {
			series: {
				shadowSize: 1
			},
			lines: {
				show: true,
				lineWidth: 0.5,
				fill: true,
				fillColor: {
					colors: [{
						opacity: 0.5
					}, {
						opacity: 1
					}]
				}
			},
			yaxis: {
				min: 0, //	max: 1000,
				tickFormatter: function(v) {
					return v + "M";
				}
			},
			xaxis: {
				show: true,
				min: 1,
				max: _xMax,
				tickSize: [50]
			},
			colors: ["#00c818", "#2030df"],
			grid: {
				tickColor: "#aaa3a3",
				borderWidth: 0
			},
			legend: {
				labelBoxBorderColor: "none",
				position: "left"
			},

		});

		// buffer pool
		_plotBufferPool = $.plot("#innodb-buffer-pool", [{
			label: "Data",
			data: 80,
			color: "#d9534f"
		}, {
			label: "Misc",
			data: 10,
			color: "orange"
		}, {
			label: "Free",
			data: 10,
			color: "green"
		}], {
			series: {
				pie: {
					show: true,
					innerRadius: 0.45,
					label: {
						show: true
					}
				}
			}
		});

		// network status
		_plotNetworkStatus = $.plot("#network-status", [], {
			series: {
				shadowSize: 1
			},
			lines: {
				show: true,
				lineWidth: 0.5,
				fill: true,
				fillColor: {
					colors: [{
						opacity: 0.5
					}, {
						opacity: 1
					}]
				}
			},
			yaxis: {
				min: 0, //	max: 1000,
				tickFormatter: function(v) {
					return v + "M";
				}
			},
			xaxis: {
				show: true,
				min: 1,
				max: _xMax,
				tickSize: [50]
			},
			colors: ["#2030df", "#00c818"],
			grid: {
				tickColor: "#aaa3a3",
				borderWidth: 0
			}
		});

		// db connection
		_plotDbConnection = $.plot($("#db-connections"), [], {
			series: {
				bars: {
					show: true,
					barWidth: 0.2,
					align: "center",
					numbers: {
						show: true
					},
				}
			},
			xaxis: {
				mode: "categories",
				tickLength: 1
			}
		});

		_ioReadData = (new Array(100)).fill([0, 0])
		_ioWriteData = (new Array(100)).fill([0, 0])
		_netRecivedData = (new Array(100)).fill([0, 0])
		_netSendData = (new Array(100)).fill([0, 0])

	},

	loadDatas: async function(params) {
		let {
			buffer_data_reads,
			buffer_data_written,
			network_send,
			network_received,
			buffer_pool_read_requests,
			buffer_pool_write_requests,
			buffer_pool_reads,
			buffer_pool_pages,
			db_connections,
			db_select,
		} = await getDbDetailApi(params)
		drawRateDatas({
			buffer_data_reads,
			buffer_data_written,
			network_received,
			network_send,
		})
		drawDbConnection(db_connections)
		drawBufferPool(buffer_pool_pages)
		return {
			selectList: db_select,
			...getBufferPoolRate({
				buffer_pool_read_requests,
				buffer_pool_write_requests,
				buffer_pool_reads,
			})
		}
	},
}

// 数据库连接图
function drawDbConnection(db_connections) {
	let datas = db_connections.map(val => {
		return [val.connect.toUpperCase(), val.count]
	})
	_plotDbConnection.setData([datas]);
	_plotDbConnection.setupGrid();
	_plotDbConnection.draw();
}

// io net图 data list [[xdata1, ydata1], [xdata2, ydata2], [xdata3, ydata3], ...]
function drawRateDatas(data) {
	let {
		buffer_data_reads,
		buffer_data_written,
		network_received,
		network_send,
	} = data
	// let ioReadRate = getRate(buffer_data_reads, 'ioRead');
	// let ioWriteRate = getRate(buffer_data_written, 'ioWrite');
	// let netRecivedRate = getRate(network_received, 'netRecived');
	// let netSendRate = getRate(network_send, 'netSend');
	let ioReadRate = parseInt(100 * Math.random(100));
	let ioWriteRate = parseInt(100 * Math.random(100));
	let netRecivedRate = parseInt(100 * Math.random(100));
	let netSendRate = parseInt(100 * Math.random(100));
	_ioReadData.shift()
	_ioWriteData.shift()
	_netRecivedData.shift()
	_netSendData.shift()

	for (let i = 0; i < _xMax; i++) {
		if (i === _xMax - 1) {
			_ioReadData[i] = [_xMax, ioReadRate]
			_ioWriteData[i] = [_xMax, ioWriteRate]
			_netRecivedData[i] = [_xMax, netRecivedRate]
			_netSendData[i] = [_xMax, netSendRate]
			break;
		}
		// _ioReadData[i] = [(i + 1), _ioReadData[i][1]]
		// _ioWriteData[i] = [(i + 1), _ioWriteData[i][1]]
		// _netRecivedData[i] = [(i + 1), _netRecivedData[i][1]]
		// _netSendData[i] = [(i + 1), _netSendData[i][1]]
		_ioReadData[i][0] = i + 1
		_ioWriteData[i][0] = i + 1
		_netRecivedData[i][0] = i + 1
		_netSendData[i][0] = i + 1
	}
	_plotDiskIO.setData([{
		data: _ioReadData,
		label: `Reading: ${ioReadRate}M`
	}, {
		data: _ioWriteData,
		label: `Written: ${ioWriteRate}M`
	}]);
	_plotDiskIO.setupGrid();
	_plotDiskIO.draw();
	_plotNetworkStatus.setData([{
		data: _netRecivedData,
		label: `Recived: ${netRecivedRate}M`
	}, {
		data: _netSendData,
		label: `Send: ${netSendRate}M`
	}])
	_plotNetworkStatus.setupGrid();
	_plotNetworkStatus.draw();
}

function drawBufferPool(buffer_pool_pages) {
	let {
		data,
		misc,
		free,
	} = buffer_pool_pages
	_plotBufferPool.setData([{
		label: `Data: ${data}`,
		data,
		color: "#d9534f"
	}, {
		label: `Misc: ${misc}`,
		data: misc,
		color: "orange"
	}, {
		label: `Free: ${free}`,
		data: free,
		color: "green"
	}]);
	_plotBufferPool.setupGrid();
	_plotBufferPool.draw();
}

function getRate(data, type) {
	// 	_rateOldData
	// ioRead
	// ioWrite
	// netRecived
	// netSend
	// 	count
	// 	time_elapsed
	let {
		count,
		time_elapsed,
	} = data
	let rate = 0;
	if (time_elapsed > _rateOldData[type].time_elapsed) {
		if (_rateOldData[type].time_elapsed > 0) {
			rate = (count - _rateOldData[type].count) / (time_elapsed - _rateOldData[type].time_elapsed) / 1024 / 1024;
			rate = rate.toFixed(2);
		}
		_rateOldData[type].count = count || 0;
		_rateOldData[type].time_elapsed = time_elapsed || 0;
	}
	return rate;
}

function getBufferPoolRate(data) {
	let {
		buffer_pool_read_requests,
		buffer_pool_write_requests,
		buffer_pool_reads,
	} = data
	let readRequestRate = 0
	let writeRequestRate = 0
	let diskReadRate = 0
	let time_elapsed = buffer_pool_read_requests.time_elapsed || 0
	let count = buffer_pool_read_requests.count || 0
	let interval = time_elapsed - _rateOldData.readRequest.time_elapsed
	if (interval != 0) {
		readRequestRate = count - _rateOldData.readRequest.count
		readRequestRate = (readRequestRate / interval / 1024).toFixed(0);
	}
	_rateOldData.readRequest.time_elapsed = time_elapsed
	_rateOldData.readRequest.count = count

	time_elapsed = buffer_pool_write_requests.time_elapsed
	count = buffer_pool_write_requests.count
	interval = time_elapsed - _rateOldData.writeRequest.time_elapsed
	if (interval != 0) {
		writeRequestRate = count - _rateOldData.writeRequest.count
		writeRequestRate = (writeRequestRate / interval / 1024).toFixed(0);
	}
	_rateOldData.writeRequest.time_elapsed = time_elapsed
	_rateOldData.writeRequest.count = count

	time_elapsed = buffer_pool_reads.time_elapsed
	count = buffer_pool_reads.count
	interval = time_elapsed - _rateOldData.diskRead.time_elapsed
	if (interval != 0) {
		diskReadRate = count - _rateOldData.diskRead.count
		diskReadRate = (diskReadRate / interval / 1024).toFixed(0);
	}
	_rateOldData.diskRead.time_elapsed = time_elapsed
	_rateOldData.diskRead.count = count

	return {
		readRequestRate,
		writeRequestRate,
		diskReadRate,
	}
}